/* wdbDbgLib.h - debugger library */

/* Copyright 1984-2004 Wind River Systems, Inc. */

/*
modification history
--------------------
03b,07jul04,elg  Add wdbDbgBpAddrCheck() definition.
03a,27may04,elg  Add _func_wdbIsNowExternal definition.
02z,01apr04,elg  Rename macros that have too generic names.
02y,09feb04,elg  Add system call check prototype.
02x,13jan04,elg  Add system call check support.
02w,27nov03,elg  Update TEXT_(UN)LOCK() to use pid.
02v,16oct03,bpn  Added back the default value of the DBG_CRET macro. Added
                 the default value of DBG_INST_ALIGN.
02u,10oct03,elg  Add debugger handler function pointer definitions.
02t,03oct03,elg  Add debugger enhancements.
02s,02oct03,elg  Rework TEXT_(UN)LOCK macros and check previous state.
02r,29sep03,tbu  Added WDB_TRACE_MODE_SET/CLEAR, USR_BREAKPOINT_SET,
		 applied coding conventions for TEXT_(UN)LOCK.
02q,12sep03,tbu  TEXT_(UN)LOCK has now 3 parameters to keep compliant to UNIXs
02p,07may03,pes  PAL conditional compilation cleanup. Phase 2.
02o,22apr03,dbt  Added SIMLINUX support, removed SIMHPPA.
02n,20feb03,jmp  removed TEXT_UNLOCK/LOCK SIMNT specific code.
02m,28feb03,elg  Merge file from BSD/OS.
02l,25apr02,jhw  Added C++ support (SPR 76304).
02k,22oct01,dee  Merge from T2.1.0 ColdFire
02j,05sep01,pch  Avoid declaring functions which will not be defined
		 according to setting of DBG_NO_SINGLE_STEP
02i,22aug00,hbh  Added SIMLINUX support.
02h,09aug00,elg  Add context locks/unlocks in TEXT_LOCK()/TEXT_UNLOCK().
02g,23may00,elp  switched to generic macro TEXT_LOCK()/TEXT_UNLOCK() for SIMNT.
02f,27apr00,elg  Update TEXT_LOCK() and TEXT_UNLOCK().
                 Declare _func_isAnLte.
02e,03apr00,elg  Change usrBreakpointSet() prototype.
02d,29mar00,elg  Code cleanup.
02c,23mar00,jgn  add new state flag for task being deleted
02b,29feb00,elg  Add _func_isPdAttached.
02a,25feb00,frf  Add SH support for T2
01z,25feb00,rlp  modified the WDB_CTX_LOAD default macro.
01y,31jan00,elg  Fix component dependencies problems.
01x,13jan00,dra  PAL: replaced CPU tests.
01w,20dec99,elp  adapted SIMNT to TEXT_LOCK() change.
01v,15dec99,rlp  modified the WDB_CTX_SAVE default macro.
01u,23nov99,elg  Add float support in WDB_FUNC_CALL.
01t,19nov99,rlp  added the WDB_CTX_SETUP macro.
01s,10nov99,gls  modified TEXT_UNLOCK() and TEXT_LOCK() definitions
01r,10nov99,elg  Add wdbDbgArchExitSet() to set exit routine.
01q,08nov99,elp  fix simTextLock() simTextUnlock() prototypes (SIMNT).
01p,08oct99,elg  Add _func_dbgPdDelete().
01o,04oct99,elg  Add extern mode support for Aeolus.
01n,30aug99,jgn  update for overlapped memory model (2) + remove non-ANSI
                 prototypes
01m,27aug99,jgn  merge in overlapping memory model
01l,11aug99,jgn  update for protection domains
01k,04aug99,elg  Replace _wdbPdget() by dbgPdGet().
01j,04aug99,elg  Fix WDB dependencies problem.
01i,26may99,elg  Add new debug facilities for protection domains.
01h,13apr99,tam  modified TEXT_UNLOCK() and TEXT_LOCK() definitions
01g,19feb99,jgn  update for protection domains
01f,14may98,dbt  fixed previous modification.
01e,13may98,dbt  added stddef.h include for offsetof definition.
01d,01may98,cym  added SIMNT support.
01c,29apr98,dbt  code cleanup.
01b,15apr98,kkk  added ARM support.
01a,07oct97,dbt  written
*/

#ifndef __INCwdbDbgLibh
#define __INCwdbDbgLibh

#ifdef __cplusplus
extern "C" {
#endif

/* includes */

#include "vxWorks.h"

#if     CPU_FAMILY == I960
#include "arch/i960/dbgI960Lib.h"
#endif  /* CPU_FAMILY == I960 */

#if     CPU_FAMILY == MIPS
#include "arch/mips/dbgMipsLib.h"
#endif  /* CPU_FAMILY == MIPS */

#if     CPU_FAMILY == PPC
#include "arch/ppc/dbgPpcLib.h"
#endif  /* CPU_FAMILY == PPC */

#if     CPU_FAMILY == SPARC
#include "arch/sparc/dbgSparcLib.h"
#endif  /* CPU_FAMILY == SPARC */

#if     CPU_FAMILY == SIMSPARCSOLARIS
#include "arch/simsolaris/dbgSimsolarisLib.h"
#endif  /* CPU_FAMILY == SIMSPARCSOLARIS */

#if     CPU_FAMILY == SIMLINUX
#include "arch/simlinux/dbgSimlinuxLib.h"
#endif  /* CPU_FAMILY == SIMLINUX */

#if     CPU_FAMILY == SIMNT
#include "arch/simnt/dbgSimntLib.h"
#endif  /* CPU_FAMILY == SIMNT */

#if     CPU_FAMILY==I80X86
#include "arch/i86/dbgI86Lib.h"
#endif  /* CPU_FAMILY==I80X86 */

#if     CPU_FAMILY == ARM
#include "arch/arm/dbgArmLib.h"
#endif  /* CPU_FAMILY == ARM */

#if     CPU_FAMILY == COLDFIRE
#include "arch/coldfire/dbgColdfireLib.h"
#endif  /* CPU_FAMILY == COLDFIRE */

#if     CPU_FAMILY == SH
#include "arch/sh/dbgShLib.h"
#endif  /* CPU_FAMILY == SH */


#ifndef _ASMLANGUAGE
#include "wdb/dll.h"
#include "wdb/wdbRegs.h"
#include "esf.h"
#include "stddef.h"

#include "private/vmLibP.h"
#include "private/rtpLibP.h"

#ifndef	_WRS_ADJUST_PC_FOR_BRANCH_DELAY
#define	_WRS_ADJUST_PC_FOR_BRANCH_DELAY(pReg)	{}
#endif	/* _WRS_ADJUST_PC_FOR_BRANCH_DELAY */

#ifndef	DBG_SYSCALL_CHECK
#define	DBG_SYSCALL_CHECK(pc)		FALSE
#endif	/* DBG_SYSCALL_CHECK */

/* defines */

#ifndef WDB_CTX_LOAD
#define WDB_CTX_LOAD(pRegs) _sigCtxLoad(pRegs)
#endif  /* WDB_CTX_LOAD */

#ifndef WDB_CTX_SAVE
#define WDB_CTX_SAVE(pRegs) _sigCtxSave(pRegs)
#endif  /* WDB_CTX_SAVE */

#ifndef	WDB_CTX_SETUP
#define	WDB_CTX_SETUP(pRegs, pStack, taskEntry, pArgs)			\
	_sigCtxSetup ((pRegs), (pStack), (taskEntry), (pArgs))
#endif	/* WDB_CTX_SETUP */

#define WDB_STEP		0x0001
#define WDB_STEP_OVER		0x0002
#define WDB_STEP_RANGE		0x0004
#define WDB_STEPPING		(WDB_STEP | WDB_STEP_OVER | WDB_STEP_RANGE)
#define WDB_CLEANME		0x0008
#define WDB_QUEUED		0x0010
#define WDB_TARGET		0x0020
#define WDB_STEP_TARGET		(WDB_STEP | WDB_TARGET)

/*
 * Protection domains special bit indicating that we are stepping over a
 * system call boundary. In this state no other breakpoints should be
 * present!
 */

#define WDB_STEP_SC_ENTRY	0x0040
#define WDB_PD_STOP		0x0080	/* this breakpoint stops a PD */
#define WDB_ALL_STOP		0x0100	/* this breakpoint stops all tasks */

/*
 * A special flag that allows the switch hook routines to know that the
 * delete hook has been run for this task and act accordingly.
 */

#define WDB_TASK_BEING_DELETED	0x0200

#define PD_MODE_NO_STEP_OUT	0
#define PD_MODE_STEP_OUT	1

#ifndef	BRK_HARDMASK		/* hardware breakpoint mask */
#define BRK_HARDMASK	0x0
#endif	/* BRK_HARDMASK */

#ifndef	BRK_HARDWARE		/* hardware breakpoint bit */
#define BRK_HARDWARE    0x0
#endif	/*  BRK_HARDWARE*/

#ifndef DBG_HARDWARE_BP		/* support of hardware breakpoint */
#define DBG_HARDWARE_BP 0
#endif	/* DBG_HARDWARE_BP */

#ifndef DBG_NO_SINGLE_STEP	/* trace mode (single step) support */
#define DBG_NO_SINGLE_STEP 0
#endif	/* DBG_NO_SINGLE_STEP */

#ifndef DBG_CRET		/* continue until return (cret) support */
#define	DBG_CRET	TRUE
#endif	/* DBG_CRET */

#ifndef	DBG_INST_ALIGN
#define	DBG_INST_ALIGN	4	/* default to long word alignment */
#endif

/* bp_flags values */

#define BP_INSTALLED	0x80000000	/* bp is installed */
#define BP_HOST		0x40000000	/* host breakpoint */

/* defines used only by the target shell debugger */

#define BP_SO		0x08000000	/* step over (or cret) breakpoint */
#define BP_STEP		0x04000000	/* step breakpoint */
#define BP_EVENT	0x02000000	/* windview eventpoint */

/* different types of breakpoints */

#define BP_SYS		0x00800000	/* system in external mode */
#define BP_ANY_TASK	0x00400000	/* any task in the system */
#define BP_TASK		0x00200000	/* one specified task */
#define BP_PD		0x00100000	/* all tasks of a protection domain */
#define BP_PROCESS	0x00080000	/* one specified process */
#define	BP_RTP		0x00040000	/* all tasks of a RTP */
#define BP_TYPE_MASK	(BP_SYS | BP_ANY_TASK | BP_TASK | BP_PD | BP_RTP)

#define	WDB_PAGE_SIZE		VM_PAGE_SIZE_GET ()
#define	WDB_PAGE_ADDR(addr)	(void *) ((UINT) (addr) & ~(WDB_PAGE_SIZE - 1))
#define	VM_CTX_GET(pid)	((pid) == NULL ? NULL :				\
			 ((RTP_ID) (pid))->kernelRtpCmn.memInfo->vmContextId)

/******************************************************************************
*
* TEXT_UNLOCK - unprotect memory
*
* This macro unprotects memory.
*
* RETURNS: ERROR if memory cannot be unprotected (e.g. memory is unmapped)
*          OK otherwise
*
* NOMANUAL
*/

#define	TEXT_UNLOCK(pid, addr, oldAttr)					\
	((VM_STATE_GET (VM_CTX_GET (pid), WDB_PAGE_ADDR (addr),		\
		       	oldAttr) == ERROR) ?				\
	 ERROR :							\
	 ((((*(oldAttr) & VM_STATE_MASK_WRITABLE) == VM_STATE_WRITABLE) ? \
	 	OK :							\
		VM_STATE_SET (VM_CTX_GET (pid), WDB_PAGE_ADDR (addr),	\
			      WDB_PAGE_SIZE, VM_STATE_MASK_WRITABLE,	\
			      VM_STATE_WRITABLE))))

/******************************************************************************
* 
* TEXT_LOCK - protect memory
* 
* This macro restores old memory protection settings.
*
* RETURNS: ERROR if memory cannot be reprotected (e.g. memory is unmapped)
*          OK otherwise.
*
* NOMANUAL
*/

#define	TEXT_LOCK(pid, addr, oldAttr)					\
	(((*(oldAttr) & VM_STATE_MASK_WRITABLE) == VM_STATE_WRITABLE) ?	\
	    OK :							\
	    VM_STATE_SET (VM_CTX_GET (pid), WDB_PAGE_ADDR (addr),	\
	    		  WDB_PAGE_SIZE, VM_STATE_MASK_WRITABLE,	\
			  *(oldAttr)))
	
#define WDB_TRACE_MODE_SET(pRegs) 	wdbDbgTraceModeSet (pRegs)
#define WDB_TRACE_MODE_CLEAR(not_used, pRegs, bpData)			\
	wdbDbgTraceModeClear ((pRegs), (bpData))	
						
/* data types */

typedef struct brkpt		/* breakpoint structure */
    {
    dll_t	bp_chain;	/* breakpoint chain */
    UINT32	bp_id;		/* breakpoint ID */
    INSTR *	bp_addr;	/* breakpoint address */
    INSTR	bp_instr;	/* instruction at breakpoint address */
    int		bp_ownerId;	/* breakpoint owner task ID */
    UINT32	bp_ctxId;	/* breakpoint context ID */
    unsigned	bp_flags;	/* breakpoint flags */
    unsigned	bp_count;	/* breakpoint count */
    unsigned	bp_action;	/* action associated with breakpoint */
    void	(*bp_callRtn)();/* routine to call (if any) */
    int		bp_callArg;	/* called routine argument */
    } BRKPT;

#define STRUCT_BASE(s,m,p)	((s *)(void *)((char *)(p) - offsetof(s,m)))
#define BP_BASE(p)		(STRUCT_BASE(struct brkpt, bp_chain, (p)))

/* externals */

extern dll_t		bpList;
extern dll_t		bpFreeList;

#if     DBG_NO_SINGLE_STEP
extern FUNCPTR		_func_sysDbgTrap;	/* system debug trap handler */
extern FUNCPTR		_func_usrDbgTrap;	/* user debug trap handler */
#else   /* DBG_NO_SINGLE_STEP */
extern FUNCPTR		_func_sysDbgBreakpoint;	/* system breakpoint handler */
extern FUNCPTR		_func_usrDbgBreakpoint;	/* user breakpoint handler */
extern FUNCPTR		_func_sysDbgTrace;	/* system trace handler */
extern FUNCPTR		_func_usrDbgTrace;	/* user trace handler */
#endif  /* DBG_NO_SINGLE_STEP */

extern VOIDFUNCPTR	_func_wdbDbgSystemStop;
extern FUNCPTR		_func_wdbIsNowExternal;

/* function declarations */

extern void	wdbDbgArchInit (void);
extern void	wdbDbgBpListInit (void);
extern STATUS	wdbDbgBpFind (INSTR * pc, int context);
extern void	wdbDbgBpRemoveAll (void);
extern STATUS	wdbDbgBpRemove (BRKPT *pBp);
extern BRKPT *	wdbDbgBpAdd (INSTR * addr, int task, unsigned flags, 
			     unsigned action, unsigned count, 
			     FUNCPTR callRtn, int callArg);
extern STATUS	wdbDbgBpGet (INSTR * pc, int context, int type, BRKPT * pBp);
extern int	wdbDbgTraceModeSet (REG_SET * pRegs);
extern void	wdbDbgTraceModeClear (REG_SET * pRegs, int traceData);
#if	DBG_NO_SINGLE_STEP
extern INSTR *	wdbDbgGetNpc (REG_SET * pRegs);
extern void	wdbDbgTrap (INSTR * addr, REG_SET * pRegisters, void * pInfo, 
					void * pDbgRegSet, BOOL hardware);
#else	/* DBG_NO_SINGLE_STEP */
extern void	wdbDbgBreakpoint (void * pInfo, REG_SET * pRegisters, 
					void * pDbgRegSet, BOOL hardware);
extern void	wdbDbgTrace (void * pInfo, REG_SET * pRegisters);
#endif	/* DBG_NO_SINGLE_STEP */
#if 	DBG_HARDWARE_BP
extern void	wdbDbgRegsSet (DBG_REGS * pDbgReg);
extern void	wdbDbgRegsClear (void);
extern STATUS	wdbDbgHwBpSet (DBG_REGS * pDbgRegs, UINT32 type, UINT32 addr);
extern STATUS	wdbDbgHwBpFind (DBG_REGS *  pDbgRegs, UINT32 * pType, 
				UINT32 * pAddr);
extern STATUS	wdbDbgHwAddrCheck (UINT32 addr, UINT32 type, 
				   FUNCPTR memProbeRtn);
#endif 	/* DBG_HARDWARE_BP */
extern STATUS	dbgTaskCont (UINT32 contextId);
extern STATUS	dbgTaskStep (UINT32 contextId, UINT32 startAddr, 
			     UINT32 endAddr);
extern void	usrBreakpointSet (INSTR * addr, INSTR value, RTP_ID pid);
extern BRKPT *	wdbDbgBpPtrGet (void);
extern BOOL	wdbDbgSysCallCheck (REG_SET * pRegs);
extern STATUS	wdbDbgBpAddrCheck (RTP_ID memCtx, INSTR * addr, INSTR * val);

#endif 	/* _ASMLANGUAGE */

#ifdef __cplusplus
}
#endif

#endif	/* __INCwdbDbgLibh */
